package com.kalvan.core.security;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Map;
import java.util.Set;

/**
 * @author chenliang
 */
@Slf4j
public class Md5SignUtil {

    /**
     * 验证签名
     *
     * @param paramMap          待签名内容
     * @param excludeSignParams 排除内容
     * @param md5Key            md5t签名串
     * @return 验证结果
     */
    public static boolean checkIsSignValid(Map paramMap, Set<String> excludeSignParams, String md5Key) {
        String signParam = String.valueOf(paramMap.get("sign"));
        if (StringUtils.isBlank(signParam)) {
            log.error(" sign does not exist");
            return false;
        } else {
            log.info("sign:{}", signParam);
            paramMap.remove("sign");
            String sign = md5Sign(paramMap, excludeSignParams, md5Key);
            if (!sign.equalsIgnoreCase(signParam)) {
                log.error(" check sign fail");
                return false;
            } else {
                log.info(" check sign pass");
                return true;
            }
        }
    }

    /**
     * md5签名key
     *
     * @param paramMap          参数
     * @param excludeSignParams 排除参数
     * @param md5Key            签名key
     * @return 签名字符串
     */
    public static String md5Sign(Map<String, String> paramMap, Set<String> excludeSignParams, String md5Key) {
        StringBuilder param = new StringBuilder(20 * paramMap.size());
        String[] keys = paramMap.keySet().toArray(new String[paramMap.size()]);
        Arrays.sort(keys);
        for (int i = 0; i < keys.length; ++i) {
            String key = keys[i];
            if (excludeSignParams == null || !excludeSignParams.contains(key)) {
                Object value = paramMap.get(key);
                if (value != null) {
                    param.append(key).append("=").append(value).append("&");
                }
            }
        }
        param.append("key").append("=").append(md5Key);
        return DigestUtils.md5Hex(param.toString()).toUpperCase();
    }
}
